#include <QtGui>
/*
 *  cpu_gui/w_im_man.cpp
 *  
 *              CPU Monitor 
 *
 *    Spring Semester.  044800.    Technion.
 *   Copyright (C) 2006  Evgeny Shulman  and Elizabeth Shtrom 
 */

#include "cpu_monitor_gui.h"
#include "w_im_man.h"
#include "../cpu_parse_display/cpu_display.h"
  
 ImWindow::ImWindow( int _nrCPUs,QWidget *parent)
 	 : MonitorPageTab(parent), nrCPUs(_nrCPUs)
 {	
 	char count [20];
	imGroupBox      = new QGroupBox("Interrupt Manager");
	controlGroupBox = new QGroupBox("Control");
	
	imView = new QTreeView;
	imView->setRootIsDecorated(false);
	imView->setAlternatingRowColors(true);
	imView->setEditTriggers(QAbstractItemView::NoEditTriggers); 
  
	imList = new QStandardItemModel(IDT_ENTRIES, 3+nrCPUs);

	imList->setHeaderData(0, Qt::Horizontal,"INT");
	imList->setHeaderData(1, Qt::Horizontal,"Total");
	PDEBUG  ( "GUI: interrupt monitor init for %d  cpus \n", nrCPUs ); 	
	for( int  i=0;i<nrCPUs ; i++){
		imList->setHeaderData(i+2, Qt::Horizontal, QString("cpu<%1>").arg (i+1) );
	}
	imList->setHeaderData(nrCPUs+2, Qt::Horizontal, "" );

 	imView->setModel(imList);
	
	for (int i =0 ; i< IDT_ENTRIES ; i ++ ) {
		sprintf( count, "0x%2.2x(%d)", i, i);
		imList->setData (imList->index(i, 0) , count);
	}
    
    im_lbl = new QLabel("  Not Started");
    

	QVBoxLayout *imGroupBoxLayout = new QVBoxLayout;
	imGroupBoxLayout->addWidget(imView);
		 
	imGroupBox->setLayout(imGroupBoxLayout);
     
     
//   	control_1_lcd     = new QLCDNumber;        
//	control_1_lbl     = new QLabel ("Lab1");     
//	
//	control_2_lcd     = new QLCDNumber;        
//	control_2_lbl     = new QLabel;     
    
	control_time_lcd  = new QLCDNumber;     
	control_time_lbl  = new QLabel("Time");     
	
	control_total_lcd = new QLCDNumber;    
	control_total_lbl = new QLabel("Total");
	
	read_btn          = new QPushButton ("Read") ;            
	reset_btn         = new QPushButton ("Reset") ;            
	start_stop_btn         = new QPushButton ("Start") ;            
	QVBoxLayout *controlButtonLayout = new QVBoxLayout;
	controlButtonLayout->addWidget(read_btn);
	controlButtonLayout->addWidget(reset_btn);
	controlButtonLayout->addWidget(start_stop_btn);
	


	QGridLayout *controlGridLayout = new QGridLayout();
//	controlGridLayout->addWidget(control_1_lbl,    0, 0);
//	controlGridLayout->addWidget(control_1_lcd,    0, 1);
//	controlGridLayout->addWidget(control_2_lbl,    1, 0);
//	controlGridLayout->addWidget(control_2_lcd,    1, 1);
	controlGridLayout->addWidget(control_time_lbl, 0, 0);
	controlGridLayout->addWidget(control_time_lcd, 0, 1);
	controlGridLayout->addWidget(control_total_lbl,1, 0);
	controlGridLayout->addWidget(control_total_lcd,1, 1);
	 
	 
	QHBoxLayout *controlGroupBoxLayout = new QHBoxLayout();
	controlGroupBoxLayout->addLayout(controlGridLayout);
	controlGroupBoxLayout->addStretch(1); 
	controlGroupBoxLayout->addLayout(controlButtonLayout);
		 
	controlGroupBox->setLayout(controlGroupBoxLayout);
	
	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->addWidget(imGroupBox);
	mainLayout->addWidget(controlGroupBox);
	mainLayout->addWidget(im_lbl);
	setLayout(mainLayout);
	
	setWindowTitle("Interrupt Manager");
	resize(500, 450);
	
	QObject::connect ( read_btn, SIGNAL (clicked() ), this, SLOT(_im_read( void) ) );
	QObject::connect ( start_stop_btn,  SIGNAL (clicked() ), this, SLOT(_im_start_stop( void) ) );
	QObject::connect ( reset_btn, SIGNAL (clicked() ), this, SLOT(_im_reset ( void) ) );
    
    timer = new QTimer(this);
    timer->setInterval (500);
    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(_im_read()));
   
 }
ImWindow::~ImWindow()
{
	int cpu =0;
	if ( im_is_started ( fd[cpu]) )
	{
		 this->_im_stop();
	 }
	 return ;
}	
		

int ImWindow::_im_start_stop( void) {
	int cpu = 0 ;
	int hooked =  im_is_started ( fd[cpu]) ;
	PDEBUG  ( "im_start_stop: hooked = %d \n", hooked ); 
	switch  ( hooked ) {
	  case 0: 
	  	if ( this->_im_start() )  
	  	 	return -1;	
		break;
	  case 1:
	  	 if ( this->_im_stop() )  
	  	 	return -1;	
		break;
	default:
		fprintf(stderr, "\nGUI:failed to check immonitor!\n");
		return -1;
	}
	return 0;
}


int ImWindow::_im_start( void) {
	int cpu = 0 ;
	if ( ! im_start(fd[cpu]) ) {
			timer->start(500);
			start_time.start();
			start_stop_btn->setText("Stop");
			im_lbl->setText("Monitor is working..");
	}else{
		fprintf(stderr, "\nGUI:failed to start immonitor!\n");
		return -1;
	}
	return 0;
}


int ImWindow::_im_stop( void) {
	int cpu = 0 ;
	if ( ! im_stop( fd[cpu]) ) {
		timer->stop();
		this->_im_read();
		start_stop_btn->setText("Start");
		im_lbl->setText("Monitor is stopped. Press Start button.");
	}else{
		fprintf(stderr, "\nGUI:failed to stop immonitor!\n");
		return -1;
	}
	return 0;
}




int ImWindow::_im_reset( void) {
	int cpu = 0 ;
	if (  im_reset( fd[cpu]) ) {
		fprintf(stderr, "\nGUI:failed to reset immonitor!\n");
		return -1;
	}
	start_time.restart();
	this->_im_read();
	control_time_lcd->display ( 0 );
	return 0;
}

int ImWindow::_im_restart( void) {
	return this->_im_reset();
}

int ImWindow::_im_read( void) {
	im_irq_stat_s im_irq_stat_data;
	int total, total_irq[IDT_ENTRIES];
	for (int i =0 ; i< IDT_ENTRIES ; i ++ ) {
		total_irq[i] =0;
	}
		
	
	//PDEBUG("_im_read:clicked :nrCPUs = %d\n", nrCPUs);
	for (int cpu =0 ; cpu< nrCPUs ; cpu ++ ) {
		//PDEBUG("_im_read: reading counters for %d cpu \n", cpu ) ;
		im_read ( fd[cpu] ,&im_irq_stat_data) ;
		for (int i =0 ; i< IDT_ENTRIES ; i ++ ) {
			total_irq[i] += im_irq_stat_data.irqs[i];
			imList->setData (imList->index(i, cpu+2) ,im_irq_stat_data.irqs[i] );
		}
		
	}
	total =0;
	for (int i =0 ; i< IDT_ENTRIES ; i ++ ) {
			total += total_irq[i];
			imList->setData (imList->index(i, 1) ,total_irq[i] );
	}
	control_total_lcd->display (total);
	control_time_lcd->display ( start_time.elapsed()  );
	
	return 0;
}



void ImWindow::set_column_int ( int column, int start, int counter, int *val ) {
	int current = start;
	while (counter--){
		imList->setData (imList->index(current, column) , val[current] );
		current++;
	}

}





